﻿using System;
using System.Collections.Generic;
using System.Text;
using eShop.Business;
using Entity;
using eShop.DataAccess;
using eShop.Model;
using eShop.Utility;

namespace eShop.Business
{
    public class CategoryManager
    {
        #region _ACTIVE_FUNCTION

        //public static void CreateCategory(Category category, List<int> associatedManufacturerIds)
        public static void CreateCategory(Category category)
        {
            if (IsCategoryNameUnique(category.ParentCategoryId, category.CategoryName) == false)
            {
                throw new InvalidOperationException("There is already a category with same name");
            }
            category.CategoryUrl = CreateCategoryUrl(category);
            if (!String.IsNullOrEmpty(category.CategoryImageUrl))
            {
                category.CategoryImageUrl = PrepareCategoryImage(category.CategoryImageUrl);
            }
            else
            {
                category.CategoryImageUrl = String.Empty;
            }

            if (!String.IsNullOrEmpty(category.CategoryBannerImageUrl))
            {
                category.CategoryBannerImageUrl = PrepareCategoryBannerImage(category.CategoryBannerImageUrl);
            }
            else
            {
                category.CategoryBannerImageUrl = string.Empty;
            }

            category.Id = CategoryDAO.CreateNewTblProductCategory(category);
            CategoryDAO.IncreaseSubCategoryCount(category.ParentCategoryId);
            //SaveCategoryAssociatedManufacturer(category.CategoryId, associatedManufacturerIds);
        }

        public static void UpdateCategory(Category category)
        {
            Category oldCategory = CategoryManager.GetCategoryById(category.Id);
            if (string.Compare(oldCategory.CategoryName, category.CategoryName, true) != 0)
            {
                if (IsCategoryNameUnique(category.ParentCategoryId, category.CategoryName) == false)
                {
                    throw new InvalidOperationException("There is already a category with same name");
                }
                category.CategoryUrl = CreateCategoryUrl(category);
            }
            if (!String.IsNullOrEmpty(category.CategoryImageUrl)
                && string.Compare(oldCategory.CategoryImageUrl, category.CategoryImageUrl, true) != 0)
            {
                category.CategoryImageUrl = PrepareCategoryImage(category.CategoryImageUrl);
                FileAccessUtility.DeleteFile(oldCategory.CategoryImageUrl);
            }

            if (!String.IsNullOrEmpty(category.CategoryBannerImageUrl)
                && string.Compare(oldCategory.CategoryBannerImageUrl, category.CategoryBannerImageUrl, true) != 0)
            {
                category.CategoryBannerImageUrl = PrepareCategoryBannerImage(category.CategoryBannerImageUrl);
                FileAccessUtility.DeleteFile(oldCategory.CategoryBannerImageUrl);
            }
            if (oldCategory.ParentCategoryId != category.ParentCategoryId)
            {
                CategoryDAO.DecreaseSubCategoryCount(oldCategory.ParentCategoryId);
                CategoryDAO.IncreaseSubCategoryCount(category.ParentCategoryId);
            }
            CategoryDAO.UpdateTblProductCategory(category);
        }

        //public static void UpdateCategory(Category category, List<int> associatedManufacturerIds)
        //{
        //    UpdateCategory(category);
        //    SaveCategoryAssociatedManufacturer(category.CategoryId, associatedManufacturerIds);
        //}

        public static Category GetCategoryById(int id)
        {
            if (id > 0)
            {
                return CategoryDAO.GetTblProductCategoryByCategoryId(id);
            }
            else
            {
                return null;
            }
        }

        public static List<Category> GetRootCategories()
        {
            return GetActiveSubCategories(SiteUtility.SuperRootCategoryId);
        }

        public static List<Category> GetActiveSubCategories(int parentCategoryId)
        {
            return CategoryDAO.GetActiveSubCategoriesByParentCategory(parentCategoryId);
        }

        public static List<Category> GetAllActiveCategoriesWithSubCategory()
        {
            List<Category> rootCategories = new List<Category>();
            List<Category> allCategories = CategoryDAO.GetAllTblProductCategory();
            allCategories.RemoveAll(c => c.IsActive == false);
            allCategories.Sort((c1, c2) => c1.DisplayOrder - c2.DisplayOrder);
            foreach (Category category in allCategories)
            {
                if (category.ParentCategoryId == SiteUtility.SuperRootCategoryId)
                {
                    rootCategories.Add(category);
                }
                else
                {
                    Category parent = allCategories.Find(c => c.Id == category.ParentCategoryId);
                    if (parent != null)
                    {
                        parent.SubCategories.Add(category);
                    }
                }
            }
            return rootCategories;
        }

        public static List<KeyValuePair<int, string>> GetAllFormatedActiveCategoriesWithSubCategory()
        {
            List<KeyValuePair<int, string>> formattedOutput = new List<KeyValuePair<int,string>>();
            FormatCategoryTree(GetAllActiveCategoriesWithSubCategory(), string.Empty, formattedOutput);
            return formattedOutput;
        }

        /****************************************/

        private static bool IsCategoryNameUnique(int parentCategoryId, string categoryName)
        {
            int count = CategoryDAO.GetProductCategoryCountByNameAndParent(parentCategoryId, categoryName);
            return count == 0;
        }

        public static string CreateCategoryUrl(Category category)
        {
            string cleanCategoryName = SiteUtility.CleanCategoryName(category.CategoryName).ToLower();
            if (category.ParentCategoryId == SiteUtility.SuperRootCategoryId)
            {
                return ApplicationSettings.CategoryRootPath + cleanCategoryName + "/";
            }
            else
            {
                Category parentCategory = GetCategoryById(category.ParentCategoryId);
                return parentCategory.CategoryUrl + cleanCategoryName + "/";
            }
        }

        private static void SaveCategoryAssociatedManufacturer(int categoryId, List<int> associatedManufacturerIds)
        {
            if (categoryId > 0)
            {
                CategoryDAO.DeleteTblPartnerCategoriesByCategoryId(categoryId);
                foreach (int manufacturerId in associatedManufacturerIds)
                {
                    CategoryDAO.CreateNewTblPartnerCategories(manufacturerId, categoryId);
                }
            }
        }

        private static string PrepareCategoryImage(string temporaryImage)
        {
            return WebPresentationUtility.CopyImageAndResize(temporaryImage,
                       ApplicationSettings.CategoryImagePath, string.Empty, ApplicationSettings.CategoryImageWidth);
        }

        private static string PrepareCategoryBannerImage(string temporaryImage)
        {
            return WebPresentationUtility.CopyImageAndResize(temporaryImage,
                    ApplicationSettings.CategoryImagePath, string.Empty, ApplicationSettings.CategoryBannerImageWidth);
        }

        private static void FormatCategoryTree(List<Category> categories, string prefix, List<KeyValuePair<int, string>> formattedOutput)
        {
            foreach (Category category in categories)
            {
                formattedOutput.Add(new KeyValuePair<int, string>(category.Id, prefix + category.CategoryName));
                FormatCategoryTree(category.SubCategories, prefix + "-- ", formattedOutput);
            }
        }

        #endregion

        
        /****************************************/
        /****************************************/
        /****************************************/


        #region _INACTIVE_FUNCTION

        public static List<KeyValuePair<string, string>> GetSubCategorySiteMapTree(int ParentCategoryId, int ChildCategoryId)
        {
            List<KeyValuePair<string, string>> productCategoryTree = new List<KeyValuePair<string, string>>();
            Category parentCategory = GetCategoryById(ParentCategoryId);
            List<Category> subCategories = new List<Category>();
            if ( parentCategory!=null)
                subCategories = GetActiveSubCategories(parentCategory.Id);
            if (parentCategory.Id == ChildCategoryId)
            {
                productCategoryTree.Add(new KeyValuePair<string, string>(parentCategory.CategoryName, parentCategory.CategoryUrl));
            }
            if (subCategories.Count > 0 && parentCategory.Id != ChildCategoryId)
            {
                foreach (Category productCategory in subCategories)
                {
                    List<KeyValuePair<string, string>> tmpTree = GetSubCategorySiteMapTree(productCategory.Id, ChildCategoryId);
                    int count = tmpTree.Count;
                    if (count > 0)
                    {
                        productCategoryTree.Add(new KeyValuePair<string, string>(parentCategory.CategoryName, parentCategory.CategoryUrl));
                    }
                    foreach (KeyValuePair<string, string> childCategory in tmpTree)
                    {
                        productCategoryTree.Add(new KeyValuePair<string, string>(childCategory.Key, childCategory.Value));
                    }
                    if (count > 0)
                    {
                        return productCategoryTree;
                    }
                }
            }

            return productCategoryTree;
        }

        public static void DeleteCategories(List<int> idList)
        {
            CategoryDAO.DeleteTblProductCategoryList(idList);
        }

        public static int GetBackendCategoryCount(bool includeDeleted)
        {
            if (includeDeleted)
            {
                return CategoryDAO.GetAllTblProductCategoryPagedCount(string.Empty, 0, 0);
            }
            else
            {
                return CategoryDAO.GetNonDeletedCategoriesCount();
            }
        }

        public static List<Category> GetBackendCategoryList(bool includeDeleted, string orderBy, int startIndex, int pageSize)
        {
            if (includeDeleted)
            {
                return CategoryDAO.GetAllTblProductCategoryPaged(orderBy, startIndex, pageSize);
            }
            else
            {
                return CategoryDAO.GetNonDeletedSubCategoriesPaged(orderBy, startIndex, pageSize);
            }
        }

        public static List<Category> GetBackendCategoryListByNameSearch(string categoryName, bool includeDeleted, string orderBy, int startIndex, int pageSize)
        {
            if (includeDeleted)
            {
                return CategoryDAO.GetAllCategoriesByNamePaged(categoryName, orderBy, startIndex, pageSize);
            }
            else
            {
                return CategoryDAO.GetNonDeletedCategoriesByNamePaged(categoryName, orderBy, startIndex, pageSize);
            }
        }

        public static int GetBackendCategoryListByNameCount(string categoryName, bool includeDeleted)
        {
            if (includeDeleted)
            {
                return CategoryDAO.GetAllCategoriesByNameCount(categoryName);
            }
            else
            {
                return CategoryDAO.GetNonDeletedCategoriesByNameCount(categoryName);
            }
        }

        public static List<Category> GetBackendCategoryListByParentCategoryIdSearch(int parentCategoryId, bool includeDeleted, string orderBy, int startIndex, int pageSize)
        {
            if (includeDeleted)
            {
                return CategoryDAO.GetTblProductCategoryByParentCategoryIdPaged(parentCategoryId, orderBy, startIndex, pageSize);
            }
            else
            {
                return CategoryDAO.GetNonDeletedSubCategoriesByParentCategoryIdPaged(parentCategoryId, orderBy, startIndex, pageSize);
            }
        }

        public static int GetBackendCategoryListByParentCategoryIdCount(int parentCategoryId, bool includeDeleted)
        {
            if (includeDeleted)
            {
                return CategoryDAO.GetTblProductCategoryByParentCategoryIdPagedCount(parentCategoryId, string.Empty, 0, 0);
            }
            else
            {
                return CategoryDAO.GetNonDeletedSubCategoriesByParentCategoryIdCount(parentCategoryId);
            }
        }


        public static List<Category> GetBackendCategoryListByParentCategoryIdAndNameSearch(int parentCategoryId, string categoryName, bool includeDeleted, string orderBy, int startIndex, int pageSize)
        {
            if (includeDeleted)
            {
                return CategoryDAO.GetAllCategoriesByParentCategoryIdAndNamePaged(parentCategoryId, categoryName, orderBy, startIndex, pageSize);
            }
            else
            {
                return CategoryDAO.GetNonDeletedCategoriesByParentCategoryIdAndNamePaged(parentCategoryId, categoryName, orderBy, startIndex, pageSize);
            }
        }

        public static int GetBackendCategoryListByParentCategoryIdAndNameCount(int parentCategoryId, string categoryName, bool includeDeleted)
        {
            if (includeDeleted)
            {
                return CategoryDAO.GetAllCategoriesByParentCategoryIdAndNameCount(parentCategoryId, categoryName);
            }
            else
            {
                return CategoryDAO.GetNonDeletedCategoriesByParentCategoryIdAndNameCount(parentCategoryId, categoryName);
            }
        }


        /**************************************************/

        public static Category GetByCategoryUrl(string categoryUrl)
        {
            return CategoryDAO.GetTblProductCategoryByUrl(categoryUrl);
        }

        #endregion
    }
}